package com.hgd.security.evp.auth.rest;

import com.hgd.security.evp.common.constances.CustomHttpStatus;
import com.hgd.security.evp.common.util.ObjectResultResponse;
import com.hgd.security.evp.common.util.StringUtil;
import lombok.extern.log4j.Log4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author By 尚
 * @date 2019/3/30 18:07
 */
@Controller
@Log4j
public class AuthenticationController {
    private RequestCache requestCache=new HttpSessionRequestCache();

    private RedirectStrategy redirectStrategy=new DefaultRedirectStrategy();

    /**
     * 响应Security拦截某一请求后的处理方法，该地下在以下进行配置
     * loginPage("/authentication/require")
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/authentication/require")
    @ResponseBody
    @ResponseStatus(code = HttpStatus.UNAUTHORIZED)
    public ObjectResultResponse requiredAuthentication(
        HttpServletRequest request, HttpServletResponse response
    ) throws IOException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if(savedRequest != null){
            String redirectUrl = savedRequest.getRedirectUrl();
            log.info("引发跳转的请求是："+redirectUrl);

            // 当进行拦截时，如果用户发送的本身就是一个登陆请求，则正常跳转到登陆页面
            if(StringUtil.endsWith(redirectUrl, "/login")){
                redirectStrategy.sendRedirect(request, response, "/login");
            }
        }

        /*
         * 如果不是一个登陆请求，则返回错误信息，告知前端进行登陆，此时前端应将页面重定向到登陆页面去
         * 因为前端与后端的交互通常会是ajax请求，所以此处需如此做
         */
        ObjectResultResponse restResult=new ObjectResultResponse();
        restResult.setMessage("引导用户到登录页");
        restResult.setStatus(CustomHttpStatus.UNAUTHORIZED);
        return restResult;
    }

    /**
     * 登陆成功后做的处理
     * 前端通过向后端发送的是ajax请求，所以在此做处理后，以ajax的形式告知前端登出成功
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/authentication/logout")
    @ResponseBody
    @ResponseStatus(code = HttpStatus.OK)
    public ObjectResultResponse logoutAuthentication(
        HttpServletRequest request, HttpServletResponse response
    ) throws IOException {
        ObjectResultResponse restResult=new ObjectResultResponse();
        restResult.setMessage("登出成功");
        return restResult;
    }
}
